%Maximize the likelihood function of the Kalman filter algorithm and return
%parameter of Kalman filter
function [params] = KFRunOpt(rStock, rIndex, process)

    %1/Phi, 2/bar_beta, 3/alpha, 4/beta0, 5/big_sigma0
    %6/sigma_square_eta, 7/sigma_square_epsilon
    % Starting guess
    [n, m] = size(rStock);
    
    X = [ones(n,1) rIndex];
    %beta, 95% interval, residuals
    [b bint r] = regress(rStock, X);
    %alpha
    params(3) = b(1);
    %bar_b
    params(2) = b(2);
    %sigma_square_epsilon
    params(7) = var(r);
    
    %big_sigma0
    params(5) = 0;
    
    [bo] = regress(rStock(1:22), X(1:22,:));
    
    %beta0 = value of beta of the first windows
    params(4) = bo(2);
    
    lb(1:7) = -inf; ub(1:7) = inf;
    lb(3) = -inf;
    %params(6) = 0.01;
    
    %Random Coefficient Model
    if (process == 1)
        params(1) = 0;
        %lb(1) = 0;  ub(1) = 0;
        
        %rolling OLS 22 days
        beta_t(1) = bo(2); 
        k = 22;
        n = length(rStock) - k;
        for i=1:n
            
            rStock_Ols = rStock(i:i+k,:);
            rIndex_Ols = rIndex(i:i+k,:);
            X = [ones(length(rIndex_Ols(:,1)),1) rIndex_Ols];
            [b bint r] = regress(rStock_Ols, X);
            beta_t(i+1) = b(2);
        end
        %bar_beta
        params(2) = mean(beta_t);
        %sigma_square_eta
        params(6)= var(beta_t);
        
    %Random Walk Model
    elseif (process == 2)
       
       %Phi
       params(1) = 1;   
       %bar_beta
       params(2) = 0;
       
       lb(1) = 1;   
       ub(1) = 1;
       lb(2) = 0;   
       ub(2) = 0;
        
       %rolling OLS 22 days
        beta_t_1 = bo(2); 
        k = 22;
        n = length(rStock) - k;
        
        for i=1:n
            rStock_Ols = rStock(i:i+k,:);
            rIndex_Ols = rIndex(i:i+k,:);
            X = [ones(length(rIndex_Ols(:,1)),1) rIndex_Ols];
            [b bint r] = regress(rStock_Ols, X);
            beta_t = b(2);
            delta_beta(i) = beta_t - beta_t_1; 
        end
        
        %sigma_square_eta
        params(6)= var(delta_beta); 
        
    end
    
    x0 = params;
    
%     %Definitions Options
%     options = optimset('Display', 'iter');
%     options = optimset(options,'LargeScale','off');
%     options = optimset(options,'GradObj','on','Jacobian','off');
    options = optimset('Algorithm','active-set');
    [n, m] = size(rStock);
    %--------------------------------------------------------------------------
    %--------------------------------------------------------------------------
    %a) Use function  LSQNONLIN recursive model

    %d) Use function  FMINCON recursive model
    
    
    finalParams = fminsearchbnd(@(x)MyKFottimilsqnlfmin(x, rIndex, rStock, n, params), x0, lb, ub);
    params = finalParams;
end